#pragma once
#include"rpcCaller.hpp"
#include"../dispatcher.hpp"
#include<atomic>

class RegisterClient // 单线程连接
{
public:
    std::atomic<bool> isConnected{false};
public:
    using ptr = std::shared_ptr<RegisterClient>;
    RegisterClient(const Address& server, const std::string& name, Dispatcher::ptr dispat) 
        : _requestor(new Requestor)
        , _dispatcher(dispat)
        , _client(NetFactory::creater<MuduoClient>(server.first, server.second, name)) {
            
            // 应用层数据处理协议
            _client->setHandlerProtocol(ProtocolFactory::create<LvProtocol>());

            // 绑定回调
            _client->setMessageHander(std::bind(&Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
            _dispatcher->setCallBack<ServiceResponse>(MSG_Type::SERVICE_RES, std::bind(&Requestor::onResponse, _requestor.get(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
            _client->setConnCb(std::bind(&RegisterClient::onConnection, this, std::placeholders::_1));
            _client->setCloseCb(std::bind(&RegisterClient::closed, this, std::placeholders::_1));
        }

    ~RegisterClient() {}

    void connect()
    {
        _client->start();
    }

    // 同步发送
    // 注册. 上线.下线 
    void opMethod(SERVICE_OPTYPE op,const std::string& method, const Address& host)
    {
        BaseMessage::ptr req = createReq(op, method, host);
        std::pair<bool, BaseMessage::ptr> ret = _requestor->sendSync(_client->getClientConnection(), req, _client->getHandlerProtocol());
        if (ret.first)
        {
            ServiceResponse::ptr res = std::dynamic_pointer_cast<ServiceResponse>(ret.second);
            if (res->getRcode() != RCode::OK)
            {
                LOG_ERROR << errStr[res->getRcode()];
                return;
            }
            
            if(op == SERVICE_OPTYPE::REGISTER)    LOG_DEBUG << "服务注册成功：" << method << " " << host.first + ":" + std::to_string(host.second);
            else if(op == SERVICE_OPTYPE::OFFLINE)    LOG_DEBUG << "服务下线成功：" << method << " " << host.first + ":" + std::to_string(host.second);
            else if(op == SERVICE_OPTYPE::ONLINE)    LOG_DEBUG << "服务上线成功：" << method << " " << host.first + ":" + std::to_string(host.second);
        }

        _requestor->remove(req->getId());
    }

    bool connected()
    {
        return isConnected;
    }

    std::string getPerrAddress()
    {
        return _client->getClientConnection()->perrAddressString();    
    }

private:
    BaseMessage::ptr createReq(SERVICE_OPTYPE opType ,const std::string& method, const Address& host)
    {
        auto req = MessageFactory::create<ServiceRequest>();
        req->setType(MSG_Type::SERVICE_REQ);
        req->setId();
        req->setOptype(opType);
        req->setMethod(method);
        req->setHost(host);

        return req;
    }

    void onConnection(BaseConnection::ptr conn)
    {
        isConnected = true;
        LOG_DEBUG << "连接到: " << conn->perrAddressString();
    }

    void closed(BaseConnection::ptr conn)
    {
        LOG_DEBUG << "断开连接：" << conn->perrAddressString();
    }

private:
    Requestor::ptr _requestor;
    Dispatcher::ptr _dispatcher;
    BaseNet::ptr _client;
};